package com.sl.core.engine.transfer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sl.core.domain.dto.JsonMappingFieldDefine;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class TYJoltSpecGenerator {

    private final ObjectMapper objectMapper = new ObjectMapper();
    private final Map<String, Object> shiftSpec = new LinkedHashMap<>();
    private final List<Map<String, Object>> operations = new ArrayList<>();

    public Map<String, Object>  generateJoltSpec(List<JsonMappingFieldDefine> mappingFields) {
        shiftSpec.put("operation", "shift");
        shiftSpec.put("spec", processFields(mappingFields));
        operations.add((Map) shiftSpec);

        return operations.get(0);
    }

    private Object processFields(List<JsonMappingFieldDefine> fields) {
        Map<String, Object> result = new LinkedHashMap<>();

        for (JsonMappingFieldDefine field : fields) {
            if (field.getIsArrayFlag()) {
                handleArrayField(field, result);
            } else {
                handleSimpleField(field, result);
            }

            if (field.getChildren() != null && !field.getChildren().isEmpty()) {
                result.put(field.getMappingJsonPath(), processFields(field.getChildren()));
            }
        }

        return result;
    }

    private void handleSimpleField(JsonMappingFieldDefine field, Map<String, Object> target) {
        Map<String, Object> fieldSpec = new LinkedHashMap<>();

        if (field.getDefaultValue() != null) {
            fieldSpec.put("default", field.getDefaultValue());
        }

        fieldSpec.put("@(1," + field.getJsonPath() + ")", null);

        target.put(field.getMappingJsonPath(), fieldSpec);
    }

    private void handleArrayField(JsonMappingFieldDefine field, Map<String, Object> target) {
        Map<String, Object> arraySpec = new LinkedHashMap<>();
        Map<String, Object> itemsSpec = new LinkedHashMap<>();

        if (field.getDefaultValue() != null) {
            itemsSpec.put("default", field.getDefaultValue());
        }

        itemsSpec.put("@(1," + field.getJsonPath() + "[@index])", null);
        arraySpec.put("items", itemsSpec);
        arraySpec.put("minItems", 0);

        target.put(field.getMappingJsonPath(), arraySpec);
    }
}